const { Op, where } = require("sequelize");
const { User: db, UsersRoles, Role } = require("../models");
const { NotFound, BadRequest, Conflict } = require("http-errors");
const { success } = require("../utils/response");
const { cryptoDecode } = require("../utils/crypto");
const { createToken } = require("../utils/jwt");
const { setKey, delKey } = require("../utils/redis");
const { expiresIn } = require("../config/app");

module.exports = {
  // 登陆
  async signIn(req, res, next) {
    try {
      const { account, password } = req.query;
      if (!account) throw new BadRequest("账号不能为空");
      if (!password) throw new BadRequest("密码不能为空");

      const condition = {
        attributes: {
          exclude: ["isDelete"],
        },
        where: {
          [Op.or]: {
            username: account,
            email: account,
            phone: account,
          },
        },
      };

      const user = await db.findOne(condition);

      if (!user) throw new NotFound("用户不存在，请尝试注册后登录！");

      if (cryptoDecode(user.password) !== password)
        throw new Conflict("密码错误");

      // 生成token
      const token = createToken({ userId: user.id });

      delete user.password;

      await setKey(`token_${user.username}`, token, expiresIn);

      success(res, "登陆成功", { token, user });
    } catch (error) {
      next(error);
    }
  },
  // 注册
  async signUp(req, res, next) {
    try {
      const { username, phone, password } = req.body;

      const user = await db.create({
        username,
        phone,
        password,
        gender: 3,
        status: true,
      });

      // 为新注册的用户添加默认角色
      const role = await Role.findOne({
        where: {
          code: "TOURIST",
        },
      });

      await UsersRoles.create({
        userId: user.id,
        roleId: role.id,
      });
      success(res, "注册成功");
    } catch (error) {
      next(error);
    }
  },
  // 退出
  async logout(req, res, next) {
    try {
      await delKey(`token_${req.user.username}`);
      req.user = null;
      success(res, "退出成功");
    } catch (error) {
      next(error);
    }
  },
};
